#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define MODE_PERFORMANCE      1
#define MODE_PRECISION        2
#define MODE_BASE		         3

struct mi {
     int nr;
     char *name;
} months[] = {
	{ 1, "jan" }, { 2, "feb" }, { 3, "mar" }, { 4, "apr" },
	{ 5, "may" }, { 6, "jun" }, { 7, "jul" }, { 8, "aug" },
	{ 9, "sep" }, {10, "oct" }, {11, "nov" }, {12, "dec" }
};

struct f16_vector_short_t {
	int	x;
	int	y;
};
typedef struct f16_vector_short_t f16_vector_short_t;

struct f16_gait_type_t {
	f16_vector_short_t arm[4];
};
typedef struct f16_gait_type_t f16_gait_type_t; 

#define nr_of_months (sizeof(months)/sizeof(struct mi))
#define nr_of_entries (sizeof(angles)/sizeof(angles_t))

:

int main(int argc, char **argv)
{
	int mode;
	int i,temp;
	int no_of_cycles;
	angles_t  key, *res;

	key.step = (double) 0;
	i = 0;
	mode = 0;

	if( argc > 1 ) {
		if( strcmp( argv[1], "perf" ) == 0 ) {
			no_of_cycles = (int) atoi( (const char*) argv[2] );
			printf("Performance mode for: %d cycles\n", no_of_cycles);
			mode = MODE_PERFORMANCE;
		} 
		if( strcmp( argv[1], "prec" ) == 0 ) {
			no_of_cycles = (int) atoi( (const char*) argv[2] );
			printf("Precision mode for: %d cycles\n", no_of_cycles);
			mode = MODE_PRECISION;
		}
		if( strcmp( argv[1], "base" ) == 0 ) {
			no_of_cycles = (int) atoi( (const char*) argv[2] );
			printf("Basing mode for: %d cycles\n", no_of_cycles);
			mode = MODE_BASE;
		} 
	}

	switch( mode ) {
		case MODE_BASE:
			while( no_of_cycles-- )
			{
				key.sine = (double) rand() / RAND_MAX;
				temp =  asin(key.sine)*180/M_PI;
			}
			printf("Basing for sin(x) done for %s cycles\n", argv[2] );
			break;

		case MODE_PERFORMANCE:
			while( no_of_cycles-- )
			{
				key.sine = (double) rand() / RAND_MAX;
				res = bsearch(&key, angles, nr_of_entries, sizeof(angles_t), cmpsin );
			  	if( res == NULL ) {
					printf("'%f': is not in the look up table. Sorry\n", key.sine);
				} else {
					i++;
		//			printf("Closest to input %s is sine %f for angle = %d\n", argv[1], res->sine, res->angle );
				}
			}
			printf("Requested calculations = %s -- made look-ups = %d\n", argv[1], i );

			break;

		case MODE_PRECISION:
			printf("Input |Match |Angle |Exact\n" );
			printf("--------------------------\n" );
			while( no_of_cycles-- )
			{
				key.sine = (double) rand() / RAND_MAX;
				res = bsearch(&key, angles, nr_of_entries, sizeof(angles_t), cmpsin );
			  	if( res == NULL ) {
					printf("'%f': is not in the look up table. Sorry\n", key.sine);
				} else {
					printf("%6.4f|%6.4f|%2d.000|%6.3f\n", key.sine, res->sine, res->angle, (asin(key.sine)*180/M_PI) );
				}
			}

			break;

		default:
			printf("No mode selected.\n");
			printf("Usage: months <perf|prec|base> <count>\n\n");
			printf("perf - performance mode. It uses bsearch to look up a coarse sin value. The\n");
			printf("       resolution is set as 1 degree (91 tabulated entries for bsearch).\n");
			printf("       The performance is poor, probably due to the complicated comparision\n");
			printf("       method. I try to move it to fixed point aritmetic. Subject to improve\n");
			printf("base - does the classic sin(x) function. It is used to set the base time\n");
			printf("       required by standard implementation of sin(x), using the FPA unit.\n");
			printf("prec - generates table with sin(x) generated by the look-up routine and\n");
			printf("       compared to sin(x) generated by libm.a - stanfard mathematic library\n\n");
			printf("All argument requires the argument <count>. This argument control how many\n");
			printf("cycles will be repeated for the choosed method.\n");


			break;
	}
	
	exit(1);

	res = bsearch(&key, angles, nr_of_entries, sizeof(angles_t), cmpsin );
  	if( res == NULL )
		printf("'%s': is not in the look up table. Sorry\n", argv[1]);
	else
		printf("Closest to input %s is sine %f for angle = %d\n", argv[1], res->sine, res->angle );

/*
	qsort(months, nr_of_months, sizeof(struct mi), compmi);
	for (i = 1; i < argc; i++) {
		struct mi key, *res;
		key.name = argv[i];
		res = bsearch(&key, months, nr_of_months, sizeof(struct mi), compmi);
		if (res == NULL)
			printf("'%s': unknown month\n", argv[i]);
		else
			printf("%s: month #%d\n", res->name, res->nr);
	}
*/

	return 1;
}


